const path = require("path");
const dayjs = require("dayjs");
const uuid = require("uuid");
const express = require('express');
const swaggerJsDoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');
const expressApp = express();
const cors = require('cors');
const port = 9876;

let sqlite3 = require('sqlite3').verbose();
let Mutex = require('./Mutex');
var db = new sqlite3.Database(path.join('', 'question.db'));
let dbLock = new Mutex()

const log4js = require('log4js');
// 配置 log4js
log4js.configure({
  appenders: {
    console: {type: 'console'},
    file: {type: 'file', filename: path.join('', 'application.log')}
  },
  categories: {
    default: {appenders: ['console', 'file'], level: 'debug'}
  }
});

var nodejieba = require("nodejieba");


// 获取 logger 实例
const logger = log4js.getLogger();

// 中间件：解析 JSON 请求体
expressApp.use(express.json());
// 使用 cors 中间件
expressApp.use(cors());

expressApp.get('/test', (req, res) => {
  res.json({});
})

class RES {
  code = 200
  success = true
  data

  SUCCESS(data) {
    this.data = data;
    return this;
  }
}

expressApp.post('/api/nodejieba/cut', (req, res) => {

  let charCount = 0;
  let chineseCharCount = 0
  let content = req.body.content
  for (const c of content) {
    /**
     * 大写字母（A-Z）：65 到 90
     * 小写字母（a-z）：97 到 122
     */
    if (c.charCodeAt(0) <= 122) {
      charCount++;
    } else {
      chineseCharCount++;
    }
  }
  let result
  if (charCount > chineseCharCount) {
    result = content.split(' ')
  } else {
    result = nodejieba.cut(content);
  }

  res.json(new RES().SUCCESS(result));
})

const runSqlTrans = async (sql, arr) => {
  await db.run("BEGIN TRANSACTION")
  let runErr = await new Promise(resolve => {
    db.run(sql, arr, err => {
      resolve(err)
    })
  })
  if (runErr) {
    logger.debug('回退', runErr)
    await db.run('ROLLBACK')
  } else {
    logger.debug('提交')
    await db.run("COMMIT")
  }
}


expressApp.post('/api/nodejieba/save', async (req, res) => {
  let body = req.body;
  await dbLock.lock()

  await runSqlTrans(`
CREATE TABLE IF NOT EXISTS question(
  id TEXT,
  value TEXT,
  insert_time TEXT,
  update_time TEXT
)
  `)

  await runSqlTrans(`
INSERT INTO question VALUES(
  ?,
  ?,
  ?,
  ?
)
  `, [
    body.id || uuid.v4(),
    JSON.stringify(body.value),
    dayjs().format('YYYY-MM-DD HH:mm:ss'),
    dayjs().format('YYYY-MM-DD HH:mm:ss'),
  ])

  dbLock.unlock()

  res.json(new RES().SUCCESS({}));
})


// Swagger 配置
const swaggerOptions = {
  swaggerDefinition: {
    openapi: '3.0.0',
    info: {
      title: 'excavation',
      version: '1.0.0',
      description: '通过 express-list-endpoints 自动生成的 API 文档'
    },
    servers: [
      {
        url: `http://localhost:${port}`,
        description: '本地开发服务器'
      }
    ]
  },
  apis: [
    './index.js'
  ] // 不需要指定文件，因为我们会自动生成
};

const swaggerDocs = swaggerJsDoc(swaggerOptions);


const routes = [];
expressApp._router.stack.forEach((middleware) => {
  if (middleware.route) {
    // 这个中间件有一个路由
    const route = middleware.route;
    const method = Object.keys(route.methods)[0].toUpperCase();
    routes.push({method, path: route.path});
  } else if (middleware.name === 'router') {
    // 这是一个嵌套路由
    middleware.handle.stack.forEach((handler) => {
      const route = handler.route;
      if (route) {
        const method = Object.keys(route.methods)[0].toUpperCase();
        routes.push({method, path: route.path});
      }
    });
  }
});

// 输出所有路由
console.log(routes);

// 自动生成 Swagger 路由文档
routes.forEach(row => {
  swaggerDocs.paths = swaggerDocs.paths || {};
  swaggerDocs.paths[row.path] = swaggerDocs.paths[row.path] || {};

  swaggerDocs.paths[row.path][row.method.toLowerCase()] = {
    tags: ['auto'],
    summary: `auto ${row.method} ${row.path} 路由`,
    requestBody: {
      "required": false,
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "required": [],
            "properties": {}
          }
        }
      }
    },
    responses: {
      200: {
        description: '成功响应'
      }
    }
  };
});
expressApp.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocs));

// 启动服务器
expressApp.listen(port, () => {
  logger.debug(`
Server is running at http://localhost:${port}
API Docs available at http://localhost:${port}/api-docs
    `);
});